# coding=utf-8
# 全世界最帅的帅哥
from flask import current_app
from flask_restful import reqparse
from sqlalchemy.exc import OperationalError, SQLAlchemyError

from ysgg1_club_auth.auth_serializers.permission_serializer import PermissionListSerializer
from ysgg1_club_auth.auth_serializers.role_serializer import RoleListSerializer
from ysgg1_club_auth.constant.role_constant import RedisPrefix
from ysgg1_club_auth.constant.role_constant import RoleConstant
from ysgg1_club_comment.modules import db
from ysgg1_club_comment.modules.auth_permission import AuthPermission
from ysgg1_club_comment.modules.auth_role import AuthRole
from ysgg1_club_comment.modules.auth_role_permission import AuthRolePermission
from ysgg1_club_comment.modules.auth_user import AuthUser
from ysgg1_club_comment.modules.auth_user_role import AuthUserRole
from ysgg1_club_comment.redis_client import redis_client
from ysgg1_club_comment.utils.fbmsg import FBMsg


def register_controller():
    try:
        parser = reqparse.RequestParser()
        parser.add_argument('username', required=True, help="用户名不能为空")
        parser.add_argument('email', required=True, help="邮箱不能为空")
        parser.add_argument("password", required=True, help="密码不能为空")
        parser.add_argument('nickName')
        parser.add_argument('sex')
        parser.add_argument('avatar')
        parser.add_argument('introduce')
        parser.add_argument('extra_json')

        args = parser.parse_args()
        user_name = args.username
        email = args.email
        password = args.password
        nick_name = args.nickName
        sex = args.sex
        avatar = args.avatar
        introduce = args.introduce
        extra_json = args.extra_json

        user = AuthUser(user_name=user_name, email=email, pwd=password, nick_name=nick_name, sex=sex,
                        avatar=avatar, introduce=introduce, extra_json=extra_json)
        db.session.add(user)
        db.session.flush()
        user_id = user.id
        role = AuthRole.query.filter_by(role_key=RoleConstant.NORMAL_USER).first()
        user_role = AuthUserRole(user_id=user_id, role_id=role.id)
        db.session.add(user_role)

        auth_role_prefix = RedisPrefix.AUTH_ROLE_PREFIX
        auth_permission_prefix = RedisPrefix.AUTH_PERMISSION_PREFIX
        role_list = [role]
        role_key = auth_role_prefix + '.' + user_name
        role_info_list = RoleListSerializer(role_list).to_dict()

        permission_id_list = AuthRolePermission.query.with_entities(AuthRolePermission.permission_id).filter_by(
            role_id=role.id).all()
        permission_id_list = list(set(map(lambda role_permission: role_permission.permission_id, permission_id_list)))
        permission_list = AuthPermission.query.filter(AuthPermission.id.in_(permission_id_list)).all()
        permission_key = auth_permission_prefix + '.' + user_name
        permission_info_list = PermissionListSerializer(permission_list).to_dict()

        with redis_client.pipeline() as pipe:
            # 执行两个set命令
            pipe.set(role_key, role_info_list)
            pipe.set(permission_key, permission_info_list)
            # 执行pipeline中的所有命令
            pipe.execute()
        db.session.commit()
        return {"code": 200, "success": True, "data": True}

    except (Exception, OperationalError, SQLAlchemyError) as e:
        current_app.logger.error(e.__str__())
        db.session.rollback()
        return FBMsg.create_user_error_message()


def register_by_wx(open_id):
    try:
        user = AuthUser(user_name=open_id, nick_name="超超粉丝")
        db.session.add(user)
        db.session.flush()
        user_id = user.id
        role = AuthRole.query.filter_by(role_key=RoleConstant.NORMAL_USER).first()
        user_role = AuthUserRole(user_id=user_id, role_id=role.id)
        db.session.add(user_role)

        auth_role_prefix = RedisPrefix.AUTH_ROLE_PREFIX
        auth_permission_prefix = RedisPrefix.AUTH_PERMISSION_PREFIX
        role_list = [role]
        role_key = auth_role_prefix + '.' + open_id
        role_info_list = RoleListSerializer(role_list).to_dict()

        permission_id_list = AuthRolePermission.query.with_entities(AuthRolePermission.permission_id).filter_by(
            role_id=role.id).all()
        permission_id_list = list(set(map(lambda role_permission: role_permission.permission_id, permission_id_list)))
        permission_list = AuthPermission.query.filter(AuthPermission.id.in_(permission_id_list)).all()
        permission_key = auth_permission_prefix + '.' + open_id
        permission_info_list = PermissionListSerializer(permission_list).to_dict()

        with redis_client.pipeline() as pipe:
            # 执行两个set命令
            pipe.set(role_key, role_info_list)
            pipe.set(permission_key, permission_info_list)
            # 执行pipeline中的所有命令
            pipe.execute()
        db.session.commit()
        return {"code": 200, "success": True, "data": True}

    except (Exception, OperationalError, SQLAlchemyError) as e:
        current_app.logger.error(e.__str__())
        db.session.rollback()
        return FBMsg.create_user_error_message()
